function str = recursiveProduceTree(tree, fields, currIndex, prefix)
%field is feature name, currIndex
    % IsBranchNode is one of the required properties
    if ~isprop(tree, 'IsBranchNode')
        error('MATLAB:input', 'Input tree is not in correct format');
    end

    % fill out default values if certain arguments are not provided
    if nargin == 1
        fields = 0;
        currIndex = 1;
        prefix = '';
    elseif nargin == 2
        currIndex = 1;
        prefix = '';
    elseif nargin == 3
        prefix = '';
    end

    if iscell(fields) && ~isequal(size(tree.PredictorNames), size(fields))
        error('MATLAB:input', 'Fields dimension does not agree');
    end
    
    % check whether the current node is a leaf or a branch
    if tree.IsBranchNode(currIndex) == 1
        
        % Here we extract the index in the field to find the real name
        % 
        % Assume that fields are generated by Matlab, e.g. Var1, Var2
        % It seems that some matlab version generates headers differently
        % For example, it might have something like b1, b2
        % The following code has been changed to cope with that.
        field = tree.CutPredictor(currIndex);
        if iscell(fields)
            field = field{1};
            field = regexp(field, '\d*', 'Match');
            field = str2num(field{1}); %#ok<ST2NM>
            field = fields(field);
        end
        
        % print out the current condition for left and right subtree
        % recursively call left and right substree
        
        % TODO the conversion between number and string loses precision
        % TODO Matlab and Weka assign = differently
        if currIndex == 1
            left = copyStr(prefix,string(field),' < ',string(tree.CutPoint(currIndex)));
        else
            left = copyStr('\n',prefix,string(field),' < ',string(tree.CutPoint(currIndex)));
        end
        %lsub = recursiveProduceTree(tree,fields,tree.Children(currIndex, 1),strcat(prefix, '|   '));
        lsub = recursiveProduceTree(tree,fields,tree.Children(currIndex, 1),[prefix, '|   ']);
        right = copyStr('\n',prefix,field,' >= ',string(tree.CutPoint(currIndex)));
        %rsub = recursiveProduceTree(tree,fields,tree.Children(currIndex, 2),strcat(prefix, '|   '));
        rsub = recursiveProduceTree(tree,fields,tree.Children(currIndex, 2),[prefix, '|   ']);
        str = copyStr(left,lsub,right,rsub);
    else
        str = copyStr(': ',string(tree.NodeClass(currIndex)));
    end
    if currIndex == 1
        sizeTree = length(tree.IsBranchNode);
        leafs = sizeTree - sum(tree.IsBranchNode);
        tailStr = sprintf('Number of Leaves  : 	%d\n\nSize of the tree : 	%d',leafs, sizeTree);
        str = copyStr(str, '\n\n', tailStr);
    end
end

%function to concanat str with space
function cmbStr = copyStr(varargin)
cmbStr = '';
for n = 1:nargin
    x = string(varargin(n));
    cmbStr = cmbStr + x;
end
end